Java - RSA + AES a double layer security system - Architecture + Implementation example

Hello everyone, today we will learn a double-layer security system using RSA+AES in Java, with the help of architecture visualization and one java example.

  • Encryption's primary purpose is to protect against brute force attacks. It is composed of a cipher, the message/data, and a key (the password). With a wide range of free tools available like(Aircrack-ng, John the Ripper, Rainbow Crack, and L0phtCrack ), even baby hackers can attempt to hack passwords using brute force.
  • In my opinion, as a layperson in cryptography, multiple double-layer encryptions may not increase security, but it may slow down attackers.
  • Using encryption may cause performance issues. Or maybe not. It really depends on how you use it. If you understand just how "expensive" each part of your enterprise encryption operation is, it's possible you can avoid the expensive parts and dramatically increase the performance of your applications.
Let's see the architecture of the RSA + AES system




This is the top layer architecture of a double-layer security system.

We will explain the RSA + AES security system with the help of one Java program, you can easily implement this algorithm on another programming platform.


SecurityUtil.java

package com.knf.sibin.dev;

import java.io.UnsupportedEncodingException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import java.util.Base64.Encoder;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
* @author sibinmuhammed
*
*/
public class SecurityUtil {
private static SecretKeySpec secretKey;
private static byte[] key;
private static final String ASYMMETRIC_ALGORITHM = "RSA";

// set Key
public static void setKey(String myKey) {
MessageDigest sha = null;
try {
key = myKey.getBytes("UTF-8");
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
secretKey = new SecretKeySpec(key, "AES");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}

// method to encrypt the secret text using key
public static String encrypt(String strToEncrypt, String secret) {
try {
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64.getEncoder().encodeToString(cipher.doFinal
(strToEncrypt.getBytes("UTF-8")));
} catch (Exception e) {
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}

// method to encrypt the secret text using key
public static String decrypt(String strToDecrypt, String secret) {
try {
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return new String(cipher.doFinal(Base64.getDecoder().
decode(strToDecrypt)));
} catch (Exception e) {
System.out.println("Error while decrypting: " + e.toString());
}
return null;
}

// Get RSA keys. Uses key size of 2048.
public static Map<String, Object> getRSAKeys() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();

Map<String, Object> keys = new HashMap<String, Object>();
keys.put("private", privateKey);
keys.put("public", publicKey);
return keys;
}

// Decrypt using RSA public key
public static String decryptMessage(String encryptedText,
PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return new String(cipher.doFinal(Base64.getDecoder().
decode(encryptedText)));
}

// Encrypt using RSA private key
public static String encryptMessage(String plainText,
PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return Base64.getEncoder().encodeToString(cipher.doFinal
(plainText.getBytes()));
}

// Encrypt using RSA private key
public static String encryptMessageUsingPublic(String plainText,
PublicKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return Base64.getEncoder().encodeToString(cipher.doFinal
(plainText.getBytes()));
}

// Decrypt using RSA public key
public static String decryptMessagePrivateKey(String encryptedText,
PrivateKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return new String(cipher.doFinal(Base64.getDecoder().
decode(encryptedText)));
}

public static String secureRandomString() {
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);
Encoder encoder = Base64.getUrlEncoder().withoutPadding();
String token = encoder.encodeToString(bytes);
return token;
}
}



Below is our demo driver class to test the double-layer security system.

Demo.java

package com.knf.sibin.dev;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Map;

// Java 8 RSA+AES encryption/decryption
// Uses strong encryption with 2048 key size.
public class Demo {

public static void main(String[] args) throws Exception {

/*
* Step 1
*
* @Client: Generate Public and Private Key
*/
Map<String, Object> keys = SecurityUtil.getRSAKeys();
PrivateKey privateKey = (PrivateKey) keys.get("private");
PublicKey publicKey = (PublicKey) keys.get("public");
System.out.println("Key Pairs generated on client-side");

/*
* Step 2
*
* @Client: Sent public key to the server and save the private key on
client local storage
*
*/
System.out.println("private-key store on client-side");
System.out.println("sent public-key to server-side");

/*
* Step 3
*
* @Server: Server will generate a secure random aes_key
*/
String secure_random_aes_key = SecurityUtil.secureRandomString();
System.out.println("Generate Secure Random AES key on server-side");

/*
* Step 4
*
* @Server:Ecrypt the AES key using public key and store the AES key on
* server-side.
*/
String encrptText = SecurityUtil.encryptMessageUsingPublic
(secure_random_aes_key, publicKey);
System.out.println("Encrypted the AES key using public key");
System.out.println("AES key stored on server");

/*
* Step 5
*
* @Server:Sent encrypted AES key to client-side
*/
System.out.println("Sent encrypted AES key to client-side");

/*
* Step 6
*
* @Client: Decrypt the encrypted AES key using private key
*/
String aesKey = SecurityUtil.decryptMessagePrivateKey
(encrptText, privateKey);
System.out.println("AES key successfully decrypted");

/*
* Step 7
*
* @Client:Encrypt the secrets using AES key and sent it to server-side
*/
String enc = SecurityUtil.encrypt("password-Sibin777!88", aesKey);
System.out.println("Secret succesfully encrypted");
System.out.println("Encrypted secret successfully sent to server");

/*
* Step 8
*
* @Server:Decrypt the secret using AES key
*/
String secret = SecurityUtil.decrypt(enc, aesKey);
System.out.println("Successfully decrypted, Your secret is:" + secret);

}

}

If you execute this Java class, you will get the following output
Key Pairs generated on client-side
private-key store on client-side
sent public-key  to server-side
Generate Secure Random AES key on server-side
Encrypted the AES key using the public key
AES key stored on the server
Sent encrypted AES key to client-side
AES key successfully decrypted
Secret successfully encrypted
Encrypted secret successfully sent to the server
Successfully decrypted, Your secret is:password-Sibin777!88

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete